package multicheat;

import java.awt.Desktop;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpClientParams;

public class GoogleClient {
	
	public static void main(String[] args) {
		GoogleClient client = new GoogleClient();
		String question = "touch me";
		List<String> answers = new ArrayList<String>();
		answers.add("madonna");
		answers.add("samantha fox");
		answers.add("michael jackson");
		answers.add("duran duran");
		int answer = client.process(question, answers);
		System.out.println(answers.get(answer));
	}
	
	public int process(String question, List<String> answers) {
		return process(question, answers, false);
	}
	
	public int process(String question, List<String> answers, boolean negative) {
		try {
			//String urlbase = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&hl=en&num=1&q=";
			String urlbase = "http://www.google.co.uk/search?hl=en&num=1&q=";
			String q = URLEncoder.encode(getQuestionString(question), "UTF-8");
			
			String a = q + URLEncoder.encode(getAnswerString(answers, 0));
			String b = q + URLEncoder.encode(getAnswerString(answers, 1));
			String c = q + URLEncoder.encode(getAnswerString(answers, 2));
			String d = q + URLEncoder.encode(getAnswerString(answers, 3));
			
			//Desktop.getDesktop().browse(new URI(urlbase + a));
			//Desktop.getDesktop().browse(new URI(urlbase + b));
			//Desktop.getDesktop().browse(new URI(urlbase + c));
			//Desktop.getDesktop().browse(new URI(urlbase + d));
			
			GetMethod aM = new GetMethod(urlbase + a);
			GetMethod bM = new GetMethod(urlbase + b);
			GetMethod cM = new GetMethod(urlbase + c);
			GetMethod dM = new GetMethod(urlbase + d);
			
			HttpClient http = new HttpClient();
			http.getHostConfiguration().setProxy("webproxy", 80);
			
			http.executeMethod(aM);
			long aN = extractEstimatedResultCount(aM.getResponseBodyAsString());
			
			http.executeMethod(bM);
			long bN = extractEstimatedResultCount(bM.getResponseBodyAsString());
			
			http.executeMethod(cM);
			long cN = extractEstimatedResultCount(cM.getResponseBodyAsString());
			
			http.executeMethod(dM);
			long dN = extractEstimatedResultCount(dM.getResponseBodyAsString());
			
			aM = new GetMethod(urlbase + URLEncoder.encode(answers.get(0)));
			bM = new GetMethod(urlbase + URLEncoder.encode(answers.get(1)));
			cM = new GetMethod(urlbase + URLEncoder.encode(answers.get(2)));
			dM = new GetMethod(urlbase + URLEncoder.encode(answers.get(3)));
			
			http.executeMethod(aM);
			long aN2 = extractEstimatedResultCount(aM.getResponseBodyAsString());
			
			http.executeMethod(bM);
			long bN2 = extractEstimatedResultCount(bM.getResponseBodyAsString());
			
			http.executeMethod(cM);
			long cN2 = extractEstimatedResultCount(cM.getResponseBodyAsString());
			
			http.executeMethod(dM);
			long dN2 = extractEstimatedResultCount(dM.getResponseBodyAsString());
			
			NumberFormat format = NumberFormat.getNumberInstance();
			format.setGroupingUsed(true);
			format.setMinimumFractionDigits(4);
			format.setMaximumFractionDigits(4);

			System.out.println("a = " + aN);
			System.out.println("b = " + bN);
			System.out.println("c = " + cN);
			System.out.println("d = " + dN);
			
			System.out.println("a = " + aN2);
			System.out.println("b = " + bN2);
			System.out.println("c = " + cN2);
			System.out.println("d = " + dN2);
			
			double aResult = 1000 *(double)aN / aN2;
			double bResult = 1000 *(double)bN / bN2;
			double cResult = 1000 *(double)cN / cN2;
			double dResult = 1000 *(double)dN / dN2;
			
			System.out.println("a = " + format.format(aResult));
			System.out.println("b = " + format.format(bResult));
			System.out.println("c = " + format.format(cResult));
			System.out.println("d = " + format.format(dResult));
			
			double[] results = new double[4];
			results[0] = aResult;
			results[1] = bResult;
			results[2] = cResult;
			results[3] = dResult;
			
			if(negative) {
				return indexOfLeast(results);
			} else {
				return indexOfGreatest(results);
			}
			
		} catch(UnsupportedEncodingException ex) {
			throw new RuntimeException(ex);
		} catch(MalformedURLException ex) {
			throw new RuntimeException(ex);
		} catch(IOException ex) {
			throw new RuntimeException(ex);
		} //catch (URISyntaxException ex) {
		//	throw new RuntimeException(ex);
		//}
	}
	
	public String getQuestionString(String question) {
		StringTokenizer tokenizer = new StringTokenizer(question);
		StringBuilder builder = new StringBuilder();
		while(tokenizer.hasMoreTokens()) {
			String token = tokenizer.nextToken();
			builder.append(" +").append(token);
		}
		return builder.toString();
	}
	
	public String getAnswerString(List<String> answers, int index) {
		StringBuilder builder = new StringBuilder();
		for(int i = 0; i < answers.size(); i++) {
			if(i == index) {
				builder.append(" +\"").append(answers.get(i)).append("\"");
			} else {
				builder.append(" -\"").append(answers.get(i)).append("\"");
			}
		}
		
		return builder.toString();
	}
	
	long extractEstimatedResultCount(String response) {
		//int KEY_LENGTH= 23;
		//int index = response.indexOf("estimatedResultCount\":\"");
		//int after = response.indexOf('\"', index + KEY_LENGTH);
		
		NumberFormat parseFormat = NumberFormat.getNumberInstance();
		parseFormat.setGroupingUsed(true);
		int KEY_LENGTH = 9;
		int index = response.indexOf("about <b>");
		int after = response.indexOf("</b>", index + KEY_LENGTH);
		String number = response.substring(index + KEY_LENGTH, after);
		
		
		try {
			return parseFormat.parse(number).longValue();
		} catch (ParseException ex) {
			throw new RuntimeException(ex);
		}
		
	}
	
	int indexOfGreatest(double[] values) {
		int index = 0;
		double max = values[0];
		for(int i = 1; i < values.length; i++) {
			if(values[i] > max) {
				max = values[i];
				index = i;
			}
		}
	    return index;
	}
	
	int indexOfLeast(double[] values) {
		int index = 0;
		double min = values[0];
		for(int i = 1; i < values.length; i++) {
			if(values[i] < min) {
				min = values[i];
				index = i;
			}
		}
	    return index;
	}
}
